/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/

#include "kresources.h"
#include "kerror.h"
#include "kmemorystream.h"

void kResources::doUpdate(const std::tstring& uri, kStream* stream) {
	throw kError(_T("Updating resources is not supported by this implementation!"));
}
kDataBufferView* kResources::lock(const std::tstring& uri) {
	auto i = _lockedData.find(uri);

	if (i != _lockedData.end()) {
		_lockedResources[i->second].second++;

		return i->second;
	} else {
		kStream* stream = doOpen(uri);
		kDataBufferView* result = new kDataBuffer(stream);
		doClose(stream);

		_lockedData.insert(std::make_pair(uri, result));
		_lockedResources.insert(std::make_pair(result, std::make_pair(uri, 1)));

		return result;
	}
}
void kResources::unlock(kDataBufferView* data) {
	auto i = _lockedResources.find(data);
	if (i != _lockedResources.end()) {
		if (!--i->second.second) {
			delete data;
			_lockedData.erase(i->second.first);
			_lockedResources.erase(i);
		}
	} else {
		throw kError(_T("Invalid data buffer view passed to unlock resource!"));
	}
}
void kResources::update(const std::tstring& uri, const kDataView& data) {
	if (_lockedData.find(uri) != _lockedData.end())
		throw kError(_T("Cannot update locked resource!"));
	
	kMemoryStream stream(data, keStream_Read|keStream_Seek|keStream_Measure, false);
	doUpdate(uri, &stream);
}
kStream* kResources::open(const std::tstring& uri) {
	return doOpen(uri);
}
void kResources::close(kStream*& stream) {
	doClose(stream);
	stream = 0;
}
void kResources::update(const std::tstring& uri, kStream* stream) {
	if (_lockedData.find(uri) != _lockedData.end())
		throw kError(_T("Cannot update locked resource!"));

	doUpdate(uri, stream);
}
